package wci.frontend.pascal.parsers;

import wci.frontend.*;
import wci.frontend.pascal.*;
import wci.intermediate.*;

import static wci.frontend.pascal.PascalTokenType.*;
import static wci.frontend.pascal.PascalErrorCode.*;
import static wci.intermediate.icodeimpl.ICodeNodeTypeImpl.*;
import static wci.intermediate.icodeimpl.ICodeKeyImpl.*;

/**
 * <h1>AssignmentStatementParser</h1>
 * <p>解析一个赋值语句</p>
 * <p>Copyright (c) 2009 by Ronald Mak</p>
 * <p>For instructional purposes only.  No warranties.</p>
 */
public class AssignmentStatementParser extends StatementParser
{
    public AssignmentStatementParser(PascalParserTD parent)
    {
        super(parent);
    }

    /**
     * 解析如 a = xx+yy; 之类的赋值语句
     * @param token 第一个token，肯定是identifier了。
     * @return 语句子树根节点
     * @throws Exception
     */
    public ICodeNode parse(Token token)
        throws Exception
    {
        ICodeNode assignNode = ICodeFactory.createICodeNode(ASSIGN);
        //在符号表堆栈中查找此变量的项，如果到不到就在局部表建个新项。
        //所有表项的名都是小写
        String targetName = token.getText().toLowerCase();
        SymTabEntry targetId = symTabStack.lookup(targetName);
        if (targetId == null) {
            targetId = symTabStack.enterLocal(targetName);
        }
        targetId.appendLineNumber(token.getLineNumber());
        //跳过ID
        token = nextToken();
        //变量ID作为赋值节点的第一个孩子
        ICodeNode variableNode = ICodeFactory.createICodeNode(VARIABLE);
        variableNode.setAttribute(ID, targetId);
        assignNode.addChild(variableNode);
        // 找不到赋值:=就报错，找到就吞噬
        if (token.getType() == COLON_EQUALS) {
            token = nextToken(); 
        }
        else {
            errorHandler.flag(token, MISSING_COLON_EQUALS, this);
        }
        //解析赋值语句右边的表达式，将其子树作为赋值节点的第二个孩子
        ExpressionParser expressionParser = new ExpressionParser(this);
        assignNode.addChild(expressionParser.parse(token));
        return assignNode;
    }
}
